


/**
 * @param {string} clientId The client ID.
 * @param {string=} opt_apiKey The optional API key.
 * @extends {analytics.providers.BaseProvider} analytics.providers.BaseProvider
 * @constructor
 */
analytics.providers.GaProvider = function(clientId, opt_apiKey) {
  analytics.providers.BaseProvider.apply(this, arguments);

  this.authorize = function() {
    /** @type {boolean} */ var immediate = arguments.length ? false : true;
    /** @type {string} */
    var scope = 'https://www.googleapis.com/auth/analytics.readonly';
    window['gapi']['auth']['authorize'](
        {'client_id': clientId, 'scope': scope, 'immediate': immediate},
        handleAuthResult_);
    return false;
  };

  this.unauthorize = function() {
    jsonp_('https://accounts.google.com/o/oauth2/revoke?token=' +
        accessToken_ + '&callback=', function() {location.reload();});
  };

  this.getReports = function(profileId) {
    return reports_;
  };

  this.loadReport = function(profileId, reportId, callback) {
    var report = null;
    for (var i = 0; i < reports_.length; i++) {
      if (reportId == reports_[i]['id']) {
        report = reports_[i];
        break;
      }
    }
    var range = self_.getDateRange();
    var params = {
      'ids': 'ga:' + profileId,
      'start-date': range[0],
      'end-date': range[1]
    };

    if (report['metrics'].length)
      params['metrics'] = report['metrics'].join(',');
    if (report['dimensions'].length)
      params['dimensions'] = report['dimensions'].join(',');

    window['gapi']['client']['request']({
      'path': '/analytics/v3/data/ga',
      'params': params
    }).execute(function(results) {
      if (results['error']) {
        alert(results['error']['message']);
      } else {
        var columns = [];
        var totals = [];
        if (results['columnHeaders']) {
          for (var i = 0; i < results['columnHeaders'].length; i++) {
            var name = results['columnHeaders'][i]['name'];
            totals.push(results['totalsForAllResults'][name] || 0);
            columns.push(name.substr(3)); // Removes 'ga:' prefix.
          }
        }

        var rows = [];
        for (var i = 0; i < results['rows'].length; i++) {
          var row = results['rows'][i];
          if ('date' == columns[0] && 8 == row[0].length) {
            row[0] = row[0].substr(0, 4) + '-' + row[0].substr(4, 2) +
                '-' + row[0].substr(6, 2);
          }
          rows.push(row);
        }

        var chart = {
          'type': 'date' == columns[0] ? 'line' : 'donut' //'hoop'
        };

        var data = {
          'columns': columns,
          'rows': rows,
          'totals': totals,
          'chart': chart
        };
        //console.log(results);
        callback(data);
      }
    });
  };

  function init_() {
    jsonp_('https://apis.google.com/js/client.js?onload=', clientLoadHandler_);
  }

  function jsonp_(src, callback) {
    /** @type {string} */ var cb = 'cb_' + (+new Date);
    window[cb] = callback;
    /** @type {Element} */ var script = document.createElement('SCRIPT');
    script.type = 'text/javascript';
    script.src = src + cb;
    document.documentElement.firstChild.appendChild(script);
  }

  // This function is called after the Client Library has finished loading.
  function clientLoadHandler_() {
    window['gapi']['client']['setApiKey'](opt_apiKey || '');
    window.setTimeout(self_.authorize, 1);
  }

  function handleAuthResult_(authResult) {
    // console.log(authResult);
    if (authResult) {
      accessToken_ = authResult['access_token'];
      window['gapi']['client']['load']('analytics', 'v3', function() {
        window['gapi']['client']['request']({
          'path': '/analytics/v3/management/accounts/~all/' +
              'webproperties/~all/profiles'
        }).execute(function(results) {
          //console.log(results);
          if (results['error'] || results['code']) {
            alert(results['message'] || results['error']['message']);
          } else {
            self_.handleAuthorized(results['items'] || [], results['username']);
          }
        });
      });
    } else {
      self_.handleUnAuthorized();
    }
  }

  /**
   * The reference to current class instance. Used in private methods.
   * @type {!analytics.providers.GaProvider}
   * @private
   */
  var self_ = this;

  /**
   * @type {string}
   * @private
   */
  var accessToken_;

  /**
   * https://developers.google.com/analytics/devguides/reporting/core/dimsmets
   * @type {!Array.<Object>}
   * @private
   */
  var reports_ = [
    {'id': 1, 'name': 'Audience Overview',
      'dimensions': ['ga:date'],
      'metrics': ['ga:visits', 'ga:visitors', 'ga:pageviews']
    },
    {'id': 2, 'name': 'Traffic Sources',
      'dimensions': ['ga:source'],
      'metrics': ['ga:visits', 'ga:visitors', 'ga:pageviews']
    }
  ];

  init_();
};
